<template>
  <admin-layout>
    <contextmenu
      :itemList="menuItemList"
      :visible.sync="menuVisible"
      @select="onMenuSelect"
    />
    <tabs-head
      v-if="multiPage && routerShow"
      :active="activePage"
      :page-list="pageList"
      @change="changePage"
      @close="remove"
      @refresh="refresh"
      @contextmenu="onContextmenu"
    />
    <div
      :class="['tabs-view-content', layout, pageWidth]"
      :style="`margin-top: ${multiPage ? -24 : 0}px`"
      v-if="routerShow"
    >
      <page-toggle-transition
        :disabled="animate.disabled"
        :animate="animate.name"
        :direction="animate.direction"
        :random="animate.random"
      >
        <a-keep-alive v-if="!multiPage || cachePage" v-model="clearCaches">
          <router-view
            v-if="!cacheRefresh && insidePage"
            ref="tabContent"
            :key="$route.path"
          />
        </a-keep-alive>
        <template v-else>
          <router-view v-if="!cacheRefresh && insidePage && isSHowPage()" />
        </template>
      </page-toggle-transition>
      <span v-show="$route.meta.urlInsidePageUrl" style="height: 0;width: 0;">
        <iframeView v-if="!cacheRefresh"></iframeView>
      </span>
    </div>
  </admin-layout>
</template>

<script>
import AdminLayout from "@/layouts/AdminLayout";
import Contextmenu from "@/components/menu/Contextmenu";
import PageToggleTransition from "@/components/transition/PageToggleTransition";
import { triggerWindowResizeEvent } from "@/utils/util";
import { getI18nKey } from "@/utils/routerUtil";
import { mapState, mapMutations, mapGetters } from "vuex";
import AKeepAlive from "@/components/cache/AKeepAlive";
import TabsHead from "@/layouts/tabs/TabsHead";
const indexKey = "/system/portal/index";
import iframeView from "@/pages/system/urlInsidePage";
import store from "@/store";
import { flatTreeData } from "@/utils/util";
export default {
  name: "TabsView",
  // i18n: require("./i18n"),
  components: {
    TabsHead,
    PageToggleTransition,
    Contextmenu,
    AdminLayout,
    AKeepAlive,
    iframeView,
  },
  data() {
    return {
      isShow: false,
      routerShow: true,
      qiankunShow: false,
      clearCaches: [],
      pageList: [],
      activePage: "",
      menuVisible: false,
      refreshing: false,
      cacheRefresh: false,
      insidePage: true,
    };
  },
  computed: {
    ...mapState("setting", [
      "multiPage",
      "animate",
      "animates",
      "layout",
      "pageWidth",
      "cachePage",
    ]),
    ...mapGetters(["currentProjectCode", "activeMenu"]),
    menuItemList() {
      return [
        {
          key: "1",
          icon: "vertical-right",
          //   text: this.$ct("tabsRightMenuCloseLeft"),
          text: "关闭左侧",
        },
        {
          key: "2",
          icon: "vertical-left",
          //   text: this.$ct("tabsRightMenuCloseRight"),
          text: "关闭右侧",
        },
        {
          key: "3",
          icon: "close",
          //   text: this.$ct("tabsRightMenuCloseOthers"),
          text: "关闭其它",
        },
        {
          key: "4",
          icon: "sync",
          //   text: this.$ct("tabsRightMenuRefresh"),
          text: "刷新页面",
        },
      ];
    },
    tabsOffset() {
      return this.multiPage ? 24 : 0;
    },
    keepAlive() {
      return this.$route.meta.keepAlive;
    },
  },
  watch: {
    $route: function(newRoute, from) {
      if (this.$route.meta.urlInsidePageUrl) {
        this.insidePage = false;
      } else {
        this.insidePage = true;
      }
      this.activePage = newRoute.meta.menuCode;

      if (newRoute.meta.query && newRoute.meta.query.portalStatus == "false") {
      } else {
        if (!this.multiPage) {
          this.pageList = [this.createPage(newRoute)];
        } else if (
          this.pageList.findIndex(
            (item) => item.fullPath === newRoute.fullPath
          ) === -1
        ) {
          let newRouteData = this.createPage(newRoute);
          if (this.pageList.every((v) => v.menuCode != newRouteData.menuCode)) {
            this.pageList.push(newRouteData);
          }
        }
        if (this.multiPage) {
          this.$nextTick(() => {
            this.setCachedKey(newRoute);
          });
        }
        this.refresh(this.activePage);
      }
    },
    multiPage: function(newVal) {
      if (!newVal) {
        this.pageList = [this.createPage(this.$route)];
        this.removeListener();
      } else {
        this.addListener();
      }
    },
    tabsOffset(newVal, oldVal) {
      this.correctPageMinHeight(oldVal - newVal);
    },
    currentProjectCode: {
      handler(val) {
        this.routerShow = false;
        if (val) {
          setTimeout(() => {
            this.routerShow = true;
          }, 200);
        }
      },
    },
    activeMenu: {
      handler(val) {
        if (val) {
          setTimeout(() => {
            this.activePage = this.$route.meta.menuCode;
            this.closeOthers(this.$route);
          }, 500);
        }
      },
    },
  },
  provide() {
    return {
      closeCurrent: this.closeCurrent,
    };
  },

  created() {
    this.loadCachedTabs();
    const route = this.$route;
    if (this.pageList.every((v) => v.menuCode != route.meta.menuCode)) {
      if (!this.pageList.find((v) => v.meta.menuCode == route.meta.menuCode)) {
        this.pageList.push(this.createPage(route));
      }
    }
    this.activePage = route.meta.menuCode;
    if (this.multiPage) {
      this.$nextTick(() => {
        this.setCachedKey(route);
      });
      this.addListener();
    }
    if (this.$route.path != indexKey) {
      // this.addIndexToFirst();
    }
    if (this.$route.meta.urlInsidePageUrl) {
      this.insidePage = false;
    } else {
      this.insidePage = true;
    }
  },
  mounted() {
    this.correctPageMinHeight(-this.tabsOffset);
  },
  beforeDestroy() {
    this.removeListener();
    this.correctPageMinHeight(this.tabsOffset);
  },

  methods: {
    isSHowPage() {
      return this.$store.state.permission.menuData.length > 0;
    },
    // 将首页添加到第一位
    addIndexToFirst() {
      // if (this.pageList[0].fullPath != indexKey) {
      // 	this.pageList.splice(0, 0, {
      // 		cachedKey: '__transition-308-'+store.getters.addRouters[0].path + '/portal/index'+'172',
      // 		path: indexKey,
      // 		fullPath: indexKey,
      // 		loading: false,
      // 		title: '平台门户',
      // 		icon: 'home',
      // 		unclose: true,
      // 		_init_: true,
      // 	});
      // }
    },
    changePage(page, flag) {
      let { menuCode, fullPath } = page;
      this.activePage = menuCode;
      if (this.$route.path.startsWith("/singleProject") && !flag) {
        this.$router.push({ path: this.$route.fullPath });
      } else {
        this.$router.push({ path: fullPath });
      }
    },

    //关闭当前tab
    remove(page, next) {
      let { menuCode } = page;
      if (this.pageList.length === 1) {
        return this.$message.warning(this.$t("tabsRightMenuWarn"));
      }
      //清除缓存
      let index = this.pageList.findIndex((item) => item.menuCode === menuCode);
      this.clearCaches = this.pageList
        .splice(index, 1)
        .map((page) => page.cachedKey)
        .filter((v) => v);
      if (next) {
        this.$router.push(next);
      } else if (menuCode === this.activePage) {
        index =
          index >= this.pageList.length ? this.pageList.length - 1 : index;
        this.activePage = this.pageList[index].menuCode;
        let itemRouter =
          this.pageList.find((v) => v.menuCode == this.activePage) ?? {};
        if (itemRouter) {
          let { fullPath } = itemRouter;
          this.$router.push({
            path: fullPath,
          });
        }
      }
    },

    //刷新
    refresh(key, page, cache) {
      let { menuCode } = page ?? {};
      page =
        (page || this.pageList.find((item) => item.menuCode === key)) ?? {};
      page.loading = true;
      this.clearCache(page);
      if (menuCode === this.activePage) {
        this.reloadContent(() => (page.loading = false));
      } else {
        // 其实刷新很快，加这个延迟纯粹为了 loading 状态多展示一会儿，让用户感知刷新这一过程
        this.changePage(page);
        setTimeout(() => (page.loading = false), 500);
      }
      if (cache) {
        this.cacheRefresh = true;
        this.$nextTick(() => {
          this.cacheRefresh = false;
        });
      }
      triggerWindowResizeEvent();
      // 随机动画效果
      if (this.animate.random && !this.animate.disabled) {
        let randomName = this.animates[
          Math.floor(Math.random() * this.animates.length)
        ];
        let randomDirections =
          randomName.directions[
            Math.floor(Math.random() * randomName.directions.length)
          ];
        this.setAnimate({
          name: randomName.name,
          direction: randomDirections,
          random: true,
        });
      }
    },

    onContextmenu(page, e, index) {
      if (page) {
        e.preventDefault();
        e.meta = { ...page, tabMenuIndex: index };
        this.menuVisible = true;
      }
    },

    onMenuSelect(key, target, pageData) {
      let { fullPath } = pageData;
      switch (key) {
        case "1":
          this.closeLeft(pageData);
          break;
        case "2":
          this.closeRight(pageData);
          break;
        case "3":
          this.closeOthers(pageData);
          break;
        case "4":
          this.refresh(fullPath, pageData, true);
          break;
        default:
          break;
      }
    },
    closeCurrent() {
      this.remove(this.activePage);
    },

    //关闭其他
    closeOthers(pageKey) {
      let { name, fullPath } = pageKey;
      let { menuCode } = pageKey.meta;
      // 清除缓存  && index != 0
      const clearPages = this.pageList.filter(
        (item, index) => item.menuCode !== menuCode && !item.unclose
      );
      this.clearCaches = clearPages.map((item) => item.cachedKey);
      this.pageList = this.pageList.filter(
        (item) => !clearPages.includes(item)
      );
      // 判断跳转
      if (this.activePage != menuCode) {
        this.activePage = menuCode;
        if (!menuCode) {
          this.$router.push({
            path: fullPath,
          });
          return;
        }
        this.$router.push({ name });
      }
      // this.addIndexToFirst();
    },

    //关闭左侧
    closeLeft(pageKey) {
      let { tabMenuIndex, menuCode, name } = pageKey;
      const index = tabMenuIndex;
      // 清除缓存
      const clearPages = this.pageList.filter(
        (item, i) => i < index && !item.unclose && i != 0
      );
      this.clearCaches = clearPages.map((item) => item.cachedKey);

      this.pageList = this.pageList.filter(
        (item) => !clearPages.includes(item)
      );
      // 判断跳转
      if (!this.pageList.find((item) => item.menuCode === this.activePage)) {
        this.activePage = menuCode;
        this.$router.push({ name });
      }
      // this.addIndexToFirst();
    },

    //关闭右侧
    closeRight(page) {
      let { tabMenuIndex, menuCode, name, fullPath } = page;
      const index = tabMenuIndex;
      // 清除缓存
      const clearPages = this.pageList.filter(
        (item, i) => i > index && !item.unclose
      );
      this.clearCaches = clearPages.map((item) => item.cachedKey);
      this.pageList = this.pageList.filter(
        (item) => !clearPages.includes(item)
      );
      // 判断跳转
      if (!this.pageList.find((item) => item.menuCode === this.activePage)) {
        this.activePage = menuCode;
        if (!menuCode) {
          this.$router.push({
            path: fullPath,
          });
          return;
        }
        this.$router.push({
          name,
        });
      }
    },
    clearCache(page) {
      page._init_ = false;
      this.clearCaches = [page.cachedKey];
    },
    reloadContent(onLoaded) {
      this.refreshing = !this.refreshing;
      setTimeout(() => {
        this.refreshing = !this.refreshing;
        this.$nextTick(() => {
          this.setCachedKey(this.$route);
          if (typeof onLoaded === "function") {
            onLoaded.apply(this, []);
          }
        });
      }, 200);
    },
    pageName(page) {
      return this.$t(getI18nKey(page.keyPath));
    },
    /**
     * 添加监听器
     */
    addListener() {
      window.addEventListener("page:close", this.closePageListener, false);
      window.addEventListener("page:refresh", this.refreshPageListener, false);
      window.addEventListener("unload", this.unloadListener, false);
    },
    /**
     * 移出监听器
     */
    removeListener() {
      window.removeEventListener("page:close", this.closePageListener);
      window.removeEventListener("page:refresh", this.refreshPageListener);
      window.removeEventListener("unload", this.unloadListener);
    },
    /**
     * 页签关闭事件监听
     * @param event 页签关闭事件
     */
    closePageListener(event) {
      const { closeRoute, nextRoute } = event.detail;
      const closePath =
        typeof closeRoute === "string" ? closeRoute : closeRoute.path;
      this.remove(closePath, nextRoute);
    },
    /**
     * 页面刷新事件监听
     * @param event 页签关闭事件
     */
    refreshPageListener(event) {
      const { pageKey } = event.detail;
      this.refresh(pageKey);
    },
    /**
     * 页面 unload 事件监听器，添加页签到 session 缓存，用于刷新时保留页签
     */
    unloadListener() {
      const tabs = this.pageList.map((item) => ({ ...item, _init_: false }));
      sessionStorage.setItem(
        process.env.VUE_APP_TBAS_KEY,
        JSON.stringify(tabs)
      );
    },
    createPage(route) {
      let { params, meta, name } = route;
      return {
        keyPath: route.matched[route.matched.length - 1].path,
        // keyPath:route.fullPath,
        fullPath: route.fullPath,
        loading: false,
        title: route.meta && route.meta.title,
        icon: route.meta && route.meta.icon,
        unclose:
          route.meta && route.meta.page && route.meta.page.closable === false,
        params,
        meta,
        name,
        menuCode: meta?.menuCode,
      };
    },
    /**
     * 设置页面缓存的key
     * @param route 页面对应的路由
     */
    setCachedKey(route) {
      let { fullPath, menuCode, meta } = route;
      let page = {};
      if (!menuCode && !meta.menuCode) {
        page = this.pageList.find((item) => item.fullPath === fullPath) ?? {};
      } else {
        page = this.pageList.find(
          (item) => item.menuCode === route.meta.menuCode
        );
      }

      page.unclose =
        route.meta && route.meta.page && route.meta.page.closable === false;
      if (!page._init_) {
        // const vnode = this.$refs.tabContent.$vnode
        // page.cachedKey = vnode.key + vnode.componentOptions.Ctor.cid
        page._init_ = true;
      }
    },
    /**
     * 加载缓存的 tabs
     */
    loadCachedTabs() {
      const cachedTabsStr = sessionStorage.getItem(
        process.env.VUE_APP_TBAS_KEY
      );
      if (cachedTabsStr) {
        try {
          const cachedTabs = JSON.parse(cachedTabsStr);
          if (cachedTabs.length > 0) {
            this.pageList = cachedTabs;
          }
        } catch (e) {
          console.warn("failed to load cached tabs, got exception:", e);
        } finally {
          sessionStorage.removeItem(process.env.VUE_APP_TBAS_KEY);
        }
      }
    },
    ...mapMutations("setting", ["correctPageMinHeight", "setAnimate"]),
  },
};
</script>

<style scoped lang="less">
.tabs-view {
  margin: -16px auto 8px;

  &.head.fixed {
    // max-width: 1400px;
  }
}

.tabs-view-content {
  position: relative;
  // margin: 0 auto !important;
  margin: 10px 10px 0 !important;
  overflow: hidden;
  &.head.fixed {
    width: 1400px;
    margin: 10px auto 0 !important;
  }
}
</style>
